Skip to content

fix(reads): gate pod-scoped post + external-links reads behind canViewPod#377

Merged
samxu01 merged 1 commit into
mainfrom
fix/pod-read-leaks-followup
May 15, 2026
Merged

fix(reads): gate pod-scoped post + external-links reads behind canViewPod#377
samxu01 merged 1 commit into
mainfrom
fix/pod-read-leaks-followup

Conversation

@samxu01
Copy link
Copy Markdown
Contributor

@samxu01 samxu01 commented May 15, 2026

Closes #376. Follow-up to PR #375 (now live on dev).

Summary

  • GET /api/posts?podId=<x> now requires auth + runs the same canViewPod gate already used by /announcements and /files (members + admins + agent-dm §3.7 fan-out). Global feed (podId=global/none/unset) stays open to any authenticated user.
  • GET /api/posts/:id mirrors the same gate when the post is pod-scoped.
  • GET /api/pods/:podId/external-links adds the missing canViewPod check (parity with the routes 30 lines above it).

Why

Same admin-leak shape that PR #375 fixed on /api/pods/*. Without these gates, any authenticated user — admin or not — could read posts and external-links of pods they're not a member of, including agent-rooms.

Verification (post-PR-375 deploy)

  • GET /api/pods for xcjsam: 83 → 42 (membership-filtered)
  • GET /api/pods/<sam-demo's room>: 200 → 404
  • ?scope=all admin moderation view: returns 83 ✓
  • Talk-to still creates fresh per-user agent-rooms ✓

Test plan

  • npx jest __tests__/unit/controllers/postController — 4/4 passing
  • npx jest __tests__/unit/routes/posts — 4/4 passing
  • npx jest __tests__/unit/routes/pods — 45/45 passing (external-links list test still passes via the existing member-mock path)
  • Post-deploy: confirm GET /api/posts?podId=<other-user's-room> returns 403 for xcjsam (was 200)

…wPod

Follow-up to PR #375. Three pod-scoped read paths still admin-bypassed
and could surface other users' personal-pod content:

- GET /api/posts?podId=<x>          → no auth, no pod-visibility check
- GET /api/posts/:id                → same, when post is pod-scoped
- GET /api/pods/:podId/external-links → auth'd but no visibility check

Posts read paths now require auth (landing/marketing pages don't fetch
posts, so safe). For pod-scoped queries, both getPosts and getPostById
run the same DMService.canViewPod gate already used by /announcements
and /files — members + admins + agent-dm §3.7 fan-out, all others 403.

The global feed (`podId=global`/`none`/unset) stays open to any
authenticated user. Closes the same admin-leak shape PR #375 fixed on
GET /api/pods/* — applied here to the adjacent pod-scoped read paths
flagged in issue #376.
@samxu01 samxu01 merged commit 244a7ae into main May 15, 2026
8 checks passed
lilyshen0722 added a commit that referenced this pull request May 15, 2026
Adds a new bullet under Agent Runtime — Quick Rules covering the
membership-by-default gate on the sidebar / listing / direct-ID
surfaces (admins do NOT bypass; ?scope=all is the admin opt-in)
and the canViewPod gate that pod-scoped read endpoints must call
before returning content.

Mirrors the pod-manager skill update in commonly-skills@e2ae064.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Audit admin-bypass on adjacent pod-scoped routes (posts, external-links, announcements)

1 participant